package me.zxk.smartagriculture.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zxk.smartagriculture.common.ErrorCode;
import me.zxk.smartagriculture.dto.greenhouse.*;
import me.zxk.smartagriculture.entity.Greenhouse;
import me.zxk.smartagriculture.entity.GreenhouseSensorData;
import me.zxk.smartagriculture.repository.GreenhouseRepository;
import me.zxk.smartagriculture.repository.GreenhouseSensorDataRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 大棚服务
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class GreenhouseService {

    private final GreenhouseRepository greenhouseRepository;
    private final GreenhouseSensorDataRepository sensorDataRepository;

    /**
     * 创建大棚
     */
    @Transactional
    public GreenhouseDetailResponse createGreenhouse(Long userId, CreateGreenhouseRequest request) {
        // 检查大棚名称是否已存在
        if (greenhouseRepository.existsByUserIdAndName(userId, request.getName())) {
            throw new RuntimeException(ErrorCode.GREENHOUSE_NAME_EXISTS.getMessage());
        }

        // 创建大棚
        Greenhouse greenhouse = new Greenhouse();
        greenhouse.setUserId(userId);
        greenhouse.setName(request.getName());
        greenhouse.setCrop(request.getCrop());
        greenhouse.setArea(request.getArea());
        greenhouse.setType(request.getType());
        greenhouse.setRemark(request.getRemark());
        greenhouse.setStatus("normal");

        // 设置初始环境数据
        greenhouse.setCurrentTemperature(new BigDecimal("25.0"));
        greenhouse.setCurrentHumidity(new BigDecimal("60.0"));
        greenhouse.setCurrentLight(new BigDecimal("3000.0"));
        greenhouse.setCurrentSoilHumidity(new BigDecimal("45.0"));

        Greenhouse savedGreenhouse = greenhouseRepository.save(greenhouse);
        log.info("大棚创建成功: {} - {}", userId, request.getName());

        return convertToDetailResponse(savedGreenhouse);
    }

    /**
     * 获取大棚列表
     */
    public Page<GreenhouseListResponse> getGreenhouseList(Long userId, Pageable pageable) {
        Page<Greenhouse> greenhouses = greenhouseRepository.findByUserId(userId, pageable);
        return greenhouses.map(this::convertToListResponse);
    }

    /**
     * 获取大棚详情
     */
    public GreenhouseDetailResponse getGreenhouseDetail(Long userId, Long greenhouseId) {
        Greenhouse greenhouse = greenhouseRepository.findByIdAndUserId(greenhouseId, userId)
                .orElseThrow(() -> new RuntimeException(ErrorCode.GREENHOUSE_NOT_FOUND.getMessage()));

        return convertToDetailResponse(greenhouse);
    }

    /**
     * 更新大棚信息
     */
    @Transactional
    public GreenhouseDetailResponse updateGreenhouse(Long userId, Long greenhouseId, UpdateGreenhouseRequest request) {
        Greenhouse greenhouse = greenhouseRepository.findByIdAndUserId(greenhouseId, userId)
                .orElseThrow(() -> new RuntimeException(ErrorCode.GREENHOUSE_NOT_FOUND.getMessage()));

        // 检查大棚名称是否已存在（排除当前大棚）
        if (StringUtils.hasText(request.getName()) && !request.getName().equals(greenhouse.getName())) {
            if (greenhouseRepository.existsByUserIdAndName(userId, request.getName())) {
                throw new RuntimeException(ErrorCode.GREENHOUSE_NAME_EXISTS.getMessage());
            }
        }

        // 更新大棚信息
        if (StringUtils.hasText(request.getName())) {
            greenhouse.setName(request.getName());
        }
        if (StringUtils.hasText(request.getCrop())) {
            greenhouse.setCrop(request.getCrop());
        }
        if (request.getArea() != null) {
            greenhouse.setArea(request.getArea());
        }
        if (StringUtils.hasText(request.getType())) {
            greenhouse.setType(request.getType());
        }
        if (request.getRemark() != null) {
            greenhouse.setRemark(request.getRemark());
        }

        Greenhouse savedGreenhouse = greenhouseRepository.save(greenhouse);
        log.info("大棚信息更新成功: {} - {}", userId, greenhouseId);

        return convertToDetailResponse(savedGreenhouse);
    }

    /**
     * 删除大棚
     */
    @Transactional
    public void deleteGreenhouse(Long userId, Long greenhouseId) {
        Greenhouse greenhouse = greenhouseRepository.findByIdAndUserId(greenhouseId, userId)
                .orElseThrow(() -> new RuntimeException(ErrorCode.GREENHOUSE_NOT_FOUND.getMessage()));

        greenhouseRepository.delete(greenhouse);
        log.info("大棚删除成功: {} - {}", userId, greenhouseId);
    }

    /**
     * 获取大棚最新传感器数据
     */
    public SensorDataResponse getSensorData(Long userId, Long greenhouseId) {
        // 验证大棚所有权
        if (!greenhouseRepository.findByIdAndUserId(greenhouseId, userId).isPresent()) {
            throw new RuntimeException(ErrorCode.GREENHOUSE_ACCESS_DENIED.getMessage());
        }

        GreenhouseSensorData latestData = sensorDataRepository.findLatestByGreenhouseId(greenhouseId);
        if (latestData == null) {
            throw new RuntimeException("该大棚暂无传感器数据");
        }

        return convertToSensorDataResponse(latestData);
    }

    /**
     * 获取大棚所有传感器数据
     */
    public Page<SensorDataResponse> getAllSensorData(Long userId, Long greenhouseId,
                                                    LocalDateTime startTime, LocalDateTime endTime,
                                                    Pageable pageable) {
        // 验证大棚所有权
        if (!greenhouseRepository.findByIdAndUserId(greenhouseId, userId).isPresent()) {
            throw new RuntimeException(ErrorCode.GREENHOUSE_ACCESS_DENIED.getMessage());
        }

        Page<GreenhouseSensorData> sensorData;
        if (startTime != null && endTime != null) {
            sensorData = sensorDataRepository.findByGreenhouseIdAndRecordedAtBetween(
                    greenhouseId, startTime, endTime, pageable);
        } else {
            sensorData = sensorDataRepository.findByGreenhouseIdOrderByRecordedAtDesc(
                    greenhouseId, pageable);
        }

        return sensorData.map(this::convertToSensorDataResponse);
    }

    /**
     * 转换为列表响应DTO
     */
    private GreenhouseListResponse convertToListResponse(Greenhouse greenhouse) {
        return new GreenhouseListResponse(
                greenhouse.getId(),
                greenhouse.getName(),
                greenhouse.getCrop(),
                greenhouse.getArea(),
                greenhouse.getType(),
                greenhouse.getRemark(),
                greenhouse.getStatus(),
                greenhouse.getCurrentTemperature(),
                greenhouse.getCurrentHumidity(),
                greenhouse.getCreatedAt()
        );
    }

    /**
     * 转换为详情响应DTO
     */
    private GreenhouseDetailResponse convertToDetailResponse(Greenhouse greenhouse) {
        return new GreenhouseDetailResponse(
                greenhouse.getId(),
                greenhouse.getName(),
                greenhouse.getCrop(),
                greenhouse.getArea(),
                greenhouse.getType(),
                greenhouse.getRemark(),
                greenhouse.getStatus(),
                greenhouse.getCurrentTemperature(),
                greenhouse.getCurrentHumidity(),
                greenhouse.getCurrentLight(),
                greenhouse.getCurrentSoilHumidity(),
                greenhouse.getCreatedAt()
        );
    }

    /**
     * 转换为传感器数据响应DTO
     */
    private SensorDataResponse convertToSensorDataResponse(GreenhouseSensorData data) {
        return new SensorDataResponse(
                data.getRecordedAt(),
                data.getTemperature(),
                data.getHumidity(),
                data.getLightIntensity(),
                data.getSoilHumidity()
        );
    }
}
